package com.hsmw.api.utils;

import cn.hutool.core.collection.CollectionUtil;
import com.aliyun.dyvmsapi20170525.models.SingleCallByVoiceResponse;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.hsmw.api.controller.pub.TencentPushUtils;
import com.hsmw.api.mapper.*;
import com.hsmw.api.service.*;
import com.hsmw.api.task.Sample;
import com.hsmw.api.vo.DriverUserSortVo;
import com.hsmw.api.vo.GetRequestVehicleListDTO;
import com.htn.common.core.constant.*;
import com.htn.common.core.util.SendSmsUtil;
import com.htn.common.core.utils.StringUtils;
import com.hsmw.domain.*;
import com.hsmw.domain.vo.GpsInfoEntity;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.*;

@Component
public class PlaceAnOrderUtils {

    @Autowired
    private HsmwOrderVehicleRelationService hsmwOrderVehicleRelationService;
    @Autowired
    private HsmwOrderVehicleRelationMapper hsmwOrderVehicleRelationMapper;
    @Autowired
    private HsmwOrderMapper hsmwOrderMapper;
    @Autowired
    private HsmwUserDriverMapper hsmwUserDriverMapper;
    @Autowired
    private HsmwUserMapper hsmwUserMapper;
    @Autowired
    private HsmwOrderService hsmwOrderService;
    @Autowired
    private HsmwDriverNewsMapper hsmwDriverNewsMapper;
    @Autowired
    private HsmwOrderVehicleRequestMapper hsmwOrderVehicleRequestMapper;
    @Autowired
    private HsmwItemService hsmwItemService;
    @Autowired
    private HsmwVehicleService hsmwVehicleService;
    @Autowired
    private HsmwDriverNewsService hsmwDriverNewsService;
    @Autowired
    private HsmwRequestVehicleService hsmwRequestVehicleService;


    @Value(value = "${sms.appKey}")
    private String appKey;
    @Value(value = "${sms.channel}")
    private String channel;
    @Value(value = "${sms.smsSign}")
    private String smsSign;
    @Value(value = "${sms.appId}")
    private int appId;
    @Value(value = "${sms.orderTemplateId}")
    private int orderTemplateId;

    @Value(value = "${sms.driverTemplateId}")
    private int driverTemplateId;

    @Value(value = "${sms.orderTimeoutNoticeBiz}")
    private int orderTimeoutNoticeBiz;

    @Value(value = "${sms.textOrderTimeOut}")
    private int textOrderTimeOut;

    final static String voiceCode = "0e7fe15a-5f6a-412f-8172-9f324d8c3bce.wav";

    final static Long queryTime = 3L;

    @Autowired
    private HsmwOrderVehicleRequestService hsmwOrderVehicleRequestService;

    @Autowired
    private HsmwOrderDistributeInfoService hsmwOrderDistributeInfoService;

    @Autowired
    private HsmwUserDriverService hsmwUserDriverService;


    @Autowired
    private HsmwItemMapper hsmwItemMapper;

    @Autowired
    private HsmwPumpOperateRecordService hsmwPumpOperateRecordService;




    @Autowired
    private HsmwHtnUserMapper hsmwHtnUserMapper;





    @Autowired
    private HsmwDriverUserMapper hsmwDriverUserMapper;


    public void placeAnOrder(String requestId) {
        {


            HsmwOrderVehicleRequest hsmwOrderVehicleRequest = hsmwOrderVehicleRequestMapper.selectById(requestId);
            //分别对每一个需求进行派单
            HsmwOrder order = hsmwOrderService.getHsmwOrderById(hsmwOrderVehicleRequest.getOrderId());
            HsmwHtnUser user = hsmwHtnUserMapper.selectById(order.getCreateUser());
            java.time.Duration duration = java.time.Duration.between(LocalDateTime.now(), hsmwOrderVehicleRequest.getReachTime());
            HsmwItem itemInfo = hsmwItemService.getHsmwItemById(order.getItemId());
            List<HsmwVehicle> aviliableVehicles = new ArrayList<>();
            //	查询出来符合需求的车辆信息
            hsmwOrderVehicleRequest.setLeasingCompanyId(itemInfo.getVehicleUnitId());
            GetRequestVehicleListDTO vihicle = hsmwOrderService.getRequestVehicleListByRequestId(hsmwOrderVehicleRequest);
            //当查询出的符合需求的车辆的信息为空的时候，不进行派单
            if (StringUtils.isListNotNull(vihicle.getHsmwVehicleList())) {
                //非指定的派单vo
                List<DriverUserSortVo> driverUserSortVos = new ArrayList<>();
                //指定的派单VO
                List<DriverUserSortVo> appointDriverUserSortVos = new ArrayList<>();

                String imeiStrs = "";
                String vehicleIds = "";
                for (HsmwVehicle vehicle : vihicle.getHsmwVehicleList()) {
                    if (StringUtils.isNotBlank(vehicle.getImeiNum()) || StringUtils.isNotBlank(vehicle.getIdentifyingCode())) {
                        imeiStrs += ("," + vehicle.getImeiNum());
                        vehicleIds += ("," + vehicle.getIdentifyingCode());
                    }
                }
                //chaxun
                List<GpsInfoEntity> gpsInfoEntities = new ArrayList<>();
                if (StringUtils.isNotBlank(imeiStrs)) {
                    gpsInfoEntities = GaoDeInfoUtils.getVehicleGpsLocate(imeiStrs,vehicleIds);
                }
                List<GpsInfoEntity> finalGpsInfoEntities = gpsInfoEntities;
                for (HsmwVehicle hsmwVehicle : vihicle.getHsmwVehicleList()) {
                    List<HsmwRequestVehicle> hsmwRequestVehicles = hsmwRequestVehicleService.
                            list(new LambdaQueryWrapper<HsmwRequestVehicle>()
                                    .eq(HsmwRequestVehicle::getVehilceId, hsmwVehicle.getId()).
                                            eq(HsmwRequestVehicle::getForemanUserId, order.getItemId()));
                    if (CollectionUtil.isNotEmpty(hsmwRequestVehicles)) {
                        continue;
                    }
                    String vehicleId = hsmwVehicle.getId();
                    DriverUserSortVo driverUserSortVo = new DriverUserSortVo();
                    driverUserSortVo.setVehicleId(vehicleId);
                    //查询距离时间
                    String vehicleLocalteInfo = null;
                    String destinationLocateInfo = order.getLng() + "," + order.getLat();
                    if (finalGpsInfoEntities.size() > 0) {
                        for (GpsInfoEntity entity : finalGpsInfoEntities) {
                            if (entity.getDeviceId().equals(hsmwVehicle.getImeiNum()) || StringUtils.equals(entity.getDeviceId(),hsmwVehicle.getIdentifyingCode())) {
                                if (StringUtils.isNotBlank(entity.getGpsLat())) {
                                    vehicleLocalteInfo = entity.getGpsLon() + "," + entity.getGpsLat();
                                }
                                break;
                            }
                        }
                        if (StringUtils.isBlank(vehicleLocalteInfo)) {
                            vehicleLocalteInfo = hsmwVehicle.getMobileLocate();
                        }
                    }
                    if (StringUtils.isBlank(vehicleLocalteInfo)) {
                        vehicleLocalteInfo = hsmwVehicle.getMobileLocate();
                    }
                    if (StringUtils.isNotBlank(vehicleLocalteInfo)) {
                        HashMap calculateParam = new HashMap();
                        calculateParam.put("origin", vehicleLocalteInfo);
                        calculateParam.put("destination", destinationLocateInfo);
                        Long durationTime = GaoDeInfoUtils.calculateDistanceTime(calculateParam);
                        long sconds = duration.toMillis() / 1000;
                        if ((float) sconds / 3600 < ((float) durationTime / 3600)) {
                            continue;
                        }
                        driverUserSortVo.setMobileLocate(durationTime);
                    } else {
                        //如果通过gps的获取的距离为空  那么  车不可用，直接将距离设置为无限大
                        driverUserSortVo.setMobileLocate(100000000000L);
                    }
                    HsmwItem hsmwItem = hsmwItemService.getHsmwItemById(order.getItemId());
                    HashMap param = new HashMap();
                    param.put("vehicleId", hsmwVehicle.getId());
                    List<HsmwUserDriver> hsmwUserDrivers = hsmwUserDriverService.selectAvaliableList(hsmwVehicle.getId());
                    HsmwUserDriver driver = hsmwUserDrivers.get(0);
                    //user 信息
                    String userId = driver.getUserId();
                    HsmwHtnUser hsmwUser = hsmwHtnUserMapper.selectById(userId);
                    driverUserSortVo.setDriverList(hsmwUserDrivers);
                    driverUserSortVo.setDriverId(driver.getId());
                    driverUserSortVo.setHsmwOrder(order);
                    driverUserSortVo.setHsmwVehicle(hsmwVehicle);
                    driverUserSortVo.setHsmwUser(hsmwUser);
                    driverUserSortVo.setScore(driver.getScore());
                    if (hsmwItem != null) {
                        if (hsmwVehicle.getLeasingCompanyId().equals(hsmwItem.getVehicleUnitId())) {
                            driverUserSortVo.setVehicleUnit(1);
                            appointDriverUserSortVos.add(driverUserSortVo);
                        } else {
                            driverUserSortVo.setVehicleUnit(0);
                            driverUserSortVos.add(driverUserSortVo);
                        }
                    } else {
                        driverUserSortVo.setVehicleUnit(0);
                        driverUserSortVos.add(driverUserSortVo);
                    }
                }
                DriverUserSortVo checkedDriverSortVO = null;
                if (CollectionUtil.isNotEmpty(appointDriverUserSortVos) || CollectionUtil.isNotEmpty(driverUserSortVos)) {
                    if (CollectionUtil.isNotEmpty(appointDriverUserSortVos)) {
                        appointDriverUserSortVos = sortDriverUserSort(appointDriverUserSortVos);
                        checkedDriverSortVO = appointDriverUserSortVos.get(0);
                    } else {
                        if (CollectionUtil.isNotEmpty(driverUserSortVos)) {
                            driverUserSortVos = sortDriverUserSort(driverUserSortVos);
                            checkedDriverSortVO = driverUserSortVos.get(0);
                        }
                    }
                }

                //经过筛选，如果没有合适的司机就不进行派单
                if (StringUtils.isNotNull(checkedDriverSortVO)) {
                    //如果该需求有合适的车 那么就把该需求的状态改为 已发布
                    hsmwOrderVehicleRequest.setRequestStatus(DistributeStatusEnum.RELEASED.getValue());
                    //如果hsmwOrderVehicleRequest 更新成功 那么直接进行子订单和司机相关的操作
                    if (hsmwOrderVehicleRelationService.checkIfVehicleWorking(checkedDriverSortVO.getVehicleId())) {
                        //创建子订单信息
                        HsmwOrderVehicleRelation hsmwOrderVehicleRelation = new HsmwOrderVehicleRelation();
                        String relationId = CommonUtils.generateId(hsmwOrderVehicleRelation);
                        hsmwOrderVehicleRelation.setVehicleId(checkedDriverSortVO.getVehicleId());
                        hsmwOrderVehicleRelation.setOrderStatus(ChildOrderStatusEnum.RECEIVED.getValue());
                        hsmwOrderVehicleRelation.setOrderId(order.getId());
                        HsmwVehicle hsmwVehicle = checkedDriverSortVO.getHsmwVehicle();
                        hsmwOrderVehicleRelation.setImeiNum(hsmwVehicle.getImeiNum());
                        hsmwOrderVehicleRelation.setVehicleNum(hsmwVehicle.getVehiclePlate());
                        hsmwOrderVehicleRelation.setVehicleType(hsmwVehicle.getVehicleType());
                        hsmwOrderVehicleRelation.setVehicleModel(hsmwVehicle.getVehicleModel());
                        hsmwOrderVehicleRelation.setOrderVehicleRequestId(hsmwOrderVehicleRequest.getId());
                        hsmwOrderVehicleRelation.setExpectVolume(hsmwOrderVehicleRequest.getExpectVolume());
                        hsmwOrderVehicleRelation.setAcceptOrderTime(LocalDateTime.now());
                        hsmwOrderVehicleRelation.setId(relationId);
                        //插入数据前 判断数据是否已经改变。
                        if (hsmwOrderVehicleRequestService.compareAndUpdate(hsmwOrderVehicleRequest)) {
                            hsmwOrderVehicleRelationService.save(hsmwOrderVehicleRelation);
                            HsmwPumpOperateRecord record1 = new HsmwPumpOperateRecord();
                            record1.setOrderId(order.getId());
                            record1.setName(hsmwVehicle.getVehiclePlate());
                            record1.setUserType("");
                            record1.setCreateTime(LocalDateTime.now());
                            record1.setUsername(user.getUsername());
                            record1.setOrderStatus(PumpOrderStatusEnum.RECEIVED.getValue());
                            record1.setOperContent("接单 接单车辆为" + hsmwVehicle.getVehiclePlate());
                            hsmwPumpOperateRecordService.save(record1);
                            //针对筛选后的可以派单司机进行派单
                            //改车绑定的可用司机列表
                            List<HsmwUserDriver> hsmwUserDriverList = checkedDriverSortVO.getDriverList();
                            ///接单中的司机进行推送
                            if (CollectionUtil.isNotEmpty(hsmwUserDriverList)) {
                                for (HsmwUserDriver hsmwUserDriver : hsmwUserDriverList) {
                                    String userId1 = hsmwUserDriver.getUserId();
                                    HsmwDriverUser hsmwUsers = hsmwDriverUserMapper.selectById(userId1);
                                    if (hsmwUsers != null) {
                                        TencentPushUtils.pushMsg("系统已为您指派订单，请尽快前往APP查看，确认出发时间，以免延误工作！", hsmwUsers.getUsername(), "order_status_2");
                                        String msg = "系统已为您指派订单，请尽快前往APP查看，确认出发时间，以免延误工作！";
                                        SendSmsUtil.sendDriverSmsCode(appId, appKey, msg, orderTimeoutNoticeBiz, smsSign, hsmwUsers.getUsername());
                                        SendSmsUtil.sendBizOrderForceSms(appId, appKey, hsmwUsers.getName(), hsmwUsers.getUsername(), textOrderTimeOut, smsSign, "13520391225");
                                        try {
                                            SingleCallByVoiceResponse singleCallByVoiceResponse = Sample.SingleCallByVoice(Sample.createDyvmsapiClient(), hsmwUsers.getUsername(), voiceCode);
                                            Sample.QueryCallDetailByCallId(Sample.createDyvmsapiClient(), singleCallByVoiceResponse.body.callId, queryTime);
                                        } catch (Exception e) {
                                            e.printStackTrace();
                                        }
                                        HsmwDriverNews hsmwDriverNews = new HsmwDriverNews();
                                        hsmwDriverNews.setUserId(userId1);
                                        hsmwDriverNews.setMessage(msg);
                                        hsmwDriverNews.setAlreadyRead("0");
                                        hsmwDriverNewsService.save(hsmwDriverNews);
                                    }
                                }
                            }
                            //司机指派成功 则 将 司机状态改为 工作中
                            if (CollectionUtil.isNotEmpty(hsmwUserDriverList)) {
                                hsmwUserDriverList.stream().forEach(hsmwUserDriver -> {
                                    hsmwUserDriver.setWorkStatus(CommonConstants.DRIVER_WORK);
                                });
                            }
                            hsmwUserDriverService.updateBatchById(hsmwUserDriverList);
                            //司机抢单成功 则 将 司机状态改为  工作中
                            hsmwVehicle.setWorkStatus(CommonConstants.DRIVER_WORK);
                            hsmwVehicleService.updateById(hsmwVehicle);
                        }
                    }
                }
            }
        }
    }


    @Transactional
    public List<DriverUserSortVo> sortDriverUserSort(List<DriverUserSortVo> vos) {
        //如果选择的是
        Collections.sort(vos, new Comparator<DriverUserSortVo>() {
            @Override
            public int compare(DriverUserSortVo v1, DriverUserSortVo v2) {
                if (v2.getVehicleUnit() != (v1.getVehicleUnit())) {
                    return (v2.getVehicleUnit() - v1.getVehicleUnit());
                } else {
                    if(v2.getScore()!=v1.getScore()){
                        return Integer.parseInt(v2.getScore()) - Integer.parseInt(v1.getScore());
                    }else {
                        return (int)(v1.getMobileLocate() -v2.getMobileLocate());
                    }
                }
            }
        });
        return vos;
    }
}
